Skip to content

feat: whiteboard#1954

Open
artem-harbour wants to merge 1 commit intomainfrom
artem/whiteboard-poc
Open

feat: whiteboard#1954
artem-harbour wants to merge 1 commit intomainfrom
artem/whiteboard-poc

Conversation

@artem-harbour
Copy link
Contributor

@artem-harbour artem-harbour commented Feb 5, 2026

Linear: SD-1686, SD-1687.

  1. Implemented the core whiteboard functionality for PDF docs.
  • Data Model (Per-page JSON structure).
  • Per-Page Canvas layers (with division of scenes).
  • API & Events (Registry + Core API).
  • Konva for rendering.
  • Low coupling to PDF.

Core classes and functionality:
packages/superdoc/src/core/whiteboard

Components and UI logic:
packages/superdoc/src/components/Whiteboard

Features:

  • Whiteboard modes (select, text, draw/erase, on/off).
  • Freehand drawing and erasing.
  • Text annotations.
  • Drag & drop of stickers/images and comments (prepared text annotations).
  • Editing, moving, and deleting annotations and stickers/images on a page.
  • Import/export.
  1. Ported "Grading Papers" demo to react.
  • Ported demo to react.
  • Connected UI with whiteboard API and events.
  • Fixed and polished the layout.
  1. Fixed comments/selection for PDF docs.

@artem-harbour artem-harbour self-assigned this Feb 5, 2026
@artem-harbour artem-harbour added the don't merge Don't merge yet label Feb 5, 2026
@artem-harbour artem-harbour changed the title [WIP] feat: whiteboard feat: whiteboard Feb 6, 2026
@artem-harbour artem-harbour added ready for review and removed don't merge Don't merge yet labels Feb 6, 2026
@artem-harbour artem-harbour marked this pull request as ready for review February 6, 2026 16:36
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a763262198

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

selectionLayer.value.style.pointerEvents = 'none';
const pageNumber = getPdfPageNumberFromEvent(e);
selectionLayer.value.style.pointerEvents = 'auto';
if (!pageNumber) return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clear drag mode when pointer isn't over a PDF page

When a drag starts in whitespace/margins (no .pdf-page under the pointer), this early return exits after drag mode was enabled and pointer events were turned on for the selection layer. The subsequent mouseup path bails out on !selectionPosition and does not restore the layer state, so the overlay can keep intercepting clicks and block normal document interaction until another successful selection occurs.

Useful? React with 👍 / 👎.

Comment on lines +803 to +807
const layerBounds = selectionLayer.value.getBoundingClientRect();
const zoom = activeZoom.value / 100;
const x = (e.clientX - layerBounds.left) / zoom;
const y = (e.clientY - layerBounds.top) / zoom;
updateSelection({ startX: x, startY: y, page: pageNumber });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Measure PDF drag selection in page-local coordinates

These bounds are computed relative to the global selection layer, but the selection is now tagged with a concrete page number. Downstream comment positioning adds that page container's offset (comments-store via selection.getContainerLocation(...)), so page offsets are effectively added twice on page 2+ and comments/highlights are placed far from the user's dragged area.

Useful? React with 👍 / 👎.

Comment on lines +227 to +231
const pages = json?.pages || {};
Object.keys(pages).forEach((key) => {
const parsedIndex = Number(key);
const pageIndex = Number.isNaN(parsedIndex) ? key : parsedIndex;
const page = this.#createPage(pageIndex);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Load exported page-size metadata during whiteboard import

getWhiteboardData() exports meta.pageSizes, but setWhiteboardData() only replays pages and discards that metadata. Importing annotations created at a different zoom/page size therefore loses the source dimensions needed to map coordinates correctly, which causes misplaced whiteboard content after import in common cross-session/cross-device workflows.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant